#ifndef _st16550_h_
#define _st16550_h_ 1
/**HEADER********************************************************************
* 
* Copyright (c) 2008-2009 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: st16550.h$
* $Version : 3.5.1.0$
* $Date    : Feb-24-2010$
*
* Comments:
* 
*   This include file is used to provide information needed by
*   an application program using a 16550 chip
*
*END*********************************************************************/

/*-----------------------------------------------------------------------*/
/*
**                      CONSTANT DEFINITIONS
*/

/* Some CPUs are capable of reordered execution. It is important that
** this doesn't happen with the 16550 code. A macro maybe defined in
** the BSP that prevent reordering. If one isn't present define the
** macro to do nothing
*/
#ifndef _BSP_IO_EIEIO
#define _BSP_IO_EIEIO  // Not used by e300 core 
#endif

#ifndef _BSP_IO_ISYNC   
#define _BSP_IO_ISYNC   _PSP_ISYNC()
#endif

#ifndef _BSP_IO_SYNC    
#define _BSP_IO_SYNC    _PSP_SYNC()
#endif

/* 16550 UART bit definitions */
/*------------------------------- IER ---------------------------------*/

#define ST16550_UART_IER_DATA_AVAIL  (0x01)
#define ST16550_UART_IER_XMIT_EMPTY  (0x02)
#define ST16550_UART_IER_LINE_STATUS (0x04)
#define ST16550_UART_IER_MDM_STATUS  (0x08)

/*------------------------------- IIR ---------------------------------*/

/* IIR READ */
#define ST16550_UART_IIR_IP               (0x01)
#define ST16550_UART_IIR_MASK             (0x0E)
#define ST16550_UART_IIR_READ_FIFO_ENABLE (0xC0)

/* Possible interupt IIR_MASK values */
#define ST16550_UART_IIR_MDM_STATUS       (0x00)
#define ST16550_UART_IIR_XMIT_EMPTY       (0x02)
#define ST16550_UART_IIR_DATA_AVAIL       (0x04)
#define ST16550_UART_IIR_LINE_STATUS      (0x06)

/* IIR WRITE */
#define ST16550_UART_IIR_FIFO_ENABLE      (0x01)
#define ST16550_UART_IIR_RCVR_FIFO_RESET  (0x02)
#define ST16550_UART_IIR_XMIT_FIFO_RESET  (0x04)
#define ST16550_UART_IIR_DMA_MODE_SELECT  (0x08)
#define ST16550_UART_IIR_RCV_TRIGGER_MASK (0xC0)

/* Values for IIR receive trigger */
#define ST16550_UART_IIR_TRIGGER_LEVEL_1  (0x00)
#define ST16550_UART_IIR_TRIGGER_LEVEL_4  (0x40)
#define ST16550_UART_IIR_TRIGGER_LEVEL_8  (0x80)
#define ST16550_UART_IIR_TRIGGER_LEVEL_14 (0xC0)

/*------------------------------- LCR ---------------------------------*/

#define ST16550_UART_LCR_WORD_LEN_MASK (0x03)
#define ST16550_UART_LCR_STOP_BIT_MASK (0x04)
#define ST16550_UART_LCR_PARITY_MASK   (0x18)
#define ST16550_UART_LCR_STICK_PARITY  (0x20)
#define ST16550_UART_LCR_BREAK         (0x40)
#define ST16550_UART_LCR_DLAB          (0x80)

/* Word length values */
#define ST16550_UART_LCR_WORD_LEN5     (0x00)
#define ST16550_UART_LCR_WORD_LEN6     (0x01)
#define ST16550_UART_LCR_WORD_LEN7     (0x02)
#define ST16550_UART_LCR_WORD_LEN8     (0x03)

/* stop bit values */
#define ST16550_UART_LCR_1_STOP_BIT    (0x00)
#define ST16550_UART_LCR_2_STOP_BIT    (0x04)

/* Parity bit values */
#define ST16550_UART_LCR_PARITY_NONE   (0x00)
#define ST16550_UART_LCR_PARITY_ODD    (0x08)
#define ST16550_UART_LCR_PARITY_EVEN   (0x18)

/*------------------------------- MCR ---------------------------------*/

#define ST16550_UART_MCR_DTR         (0x01)
#define ST16550_UART_MCR_RTS         (0x02)
#define ST16550_UART_MCR_IRQ_ENABLE  (0x08)
#define ST16550_UART_MCR_LOOPBACK    (0x10)

/*------------------------------- LSR ---------------------------------*/

#define ST16550_UART_LSR_DATA_RCVD   (0x01)
#define ST16550_UART_LSR_OVERRUN     (0x02)
#define ST16550_UART_LSR_PARITYERR   (0x04)
#define ST16550_UART_LSR_FRAMEERR    (0x08)
#define ST16550_UART_LSR_BREAKRCVD   (0x10)
#define ST16550_UART_LSR_TXD_EMPTY   (0x20)
#define ST16550_UART_LSR_TX_STATUS   (0x40)
#define ST16550_UART_LSR_RX_FIFOERR  (0x80)

/*------------------------------- MSR ---------------------------------*/

#define ST16550_UART_MSR_DCTS        (0x01)
#define ST16550_UART_MSR_DDSR        (0x02)
#define ST16550_UART_MSR_TERI        (0x04)
#define ST16550_UART_MSR_DDCD        (0x08)
#define ST16550_UART_MSR_CTS         (0x10)
#define ST16550_UART_MSR_DSR         (0x20)
#define ST16550_UART_MSR_RIC         (0x40)
#define ST16550_UART_MSR_DCD         (0x80)

/*------------------------------- ICM ---------------------------------*/
#define ST16550_UART_ICM_POWER_DOWN    (0x02)
#define ST16550_UART_ICM_STATUS_CLEAR  (0x04)
#define ST16550_UART_ICM_INTERRUPT_ACK (0x08)
#define ST16550_UART_ICM_SW_RESET      (0x10)


/*------------------------------- FCR ---------------------------------*/
#define ST16550_UART_FCR_FEN           (0x01)
#define ST16550_UART_FCR_RFR           (0x02)
#define ST16550_UART_FCR_TFR           (0x04)
#define ST16550_UART_FCR_DMS           (0x08)
#define ST16550_UART_FCR_RTL           (0xC0)

/*------------------------------- DSR ---------------------------------*/
#define ST16550_UART_DSR_RXRDY         (0x01)
#define ST16550_UART_DSR_TXRDY         (0x02)

/*-----------------------------------------------------------------------*/
/*
**                      TYPE DEFINITIONS
*/

/* This is usually defined in bsp.h but in case it isn't...*/
#ifndef BSP_16550_STRIDE_SIZE
#define BSP_16550_STRIDE_SIZE (0)
#endif

#undef  STRIDE_FIELD
#if BSP_16550_STRIDE_SIZE == 0
#define STRIDE_FIELD(num)
#else
#define STRIDE_FIELD(num)       uchar RSVD_##num[BSP_16550_STRIDE_SIZE];
#endif

typedef struct res_field_le
{
   uchar RESERVED;
   STRIDE_FIELD(1)
} RES_FIELD_LE;

typedef struct res_field_be
{
   STRIDE_FIELD(1)
   uchar RESERVED;
} RES_FIELD_BE;

#if (PSP_ENDIAN == MQX_LITTLE_ENDIAN) || defined(BSP_ST16550_LITTLE_ENDIAN)
typedef struct st16550_uart_struct
{
   uchar DATA;                               /* data in/out                */
   STRIDE_FIELD(1)
   uchar IER;                                /* Interrupt enable register  */
   STRIDE_FIELD(2)
   uchar IIR;                                /* Interrupt Id register      */
   STRIDE_FIELD(3)
   uchar LCR;                                /* Line control Register      */
   STRIDE_FIELD(4)
   uchar MCR;                                /* Modem control register     */
   STRIDE_FIELD(5)
   uchar LSR;                                /* Line Status Register       */
   STRIDE_FIELD(6)
   uchar MSR;                                /* Modem status Register      */
   STRIDE_FIELD(7)
   uchar SCRATCHPAD;                         /* Uart scratchpad register   */
   STRIDE_FIELD(8)
   RES_FIELD_LE UNDEF[8];
   uchar DSR;                                /* DMA status register        */
   STRIDE_FIELD(9)
} ST16550_UART_STRUCT, _PTR_ ST16550_UART_STRUCT_PTR;


typedef struct st16550_parallel_port_struct
{
   uchar DATA;                               /* data in/out                */
   STRIDE_FIELD(1)
   uchar STATUS;                             /* Status register            */
   STRIDE_FIELD(2)
   uchar COMMAND;                            /* Command register           */
   STRIDE_FIELD(3)
} ST16550_PARALLEL_PORT_STRUCT, _PTR_ ST16550_PARALLEL_PORT_STRUCT_PTR;

#else /*!(PSP_ENDIAN == MQX_LITTLE_ENDIAN) || defined(BSP_ST16550_LITTLE_ENDIAN)*/
/* --- BIG_ENDIAN --- */
typedef struct st16550_uart_struct
{
   STRIDE_FIELD(1)
   uchar DATA;                               /* data in/out                */
   STRIDE_FIELD(2)
   uchar IER;                                /* Interrupt enable register  */
   STRIDE_FIELD(3)
   uchar IIR;                                /* Interrupt Id register      */
   STRIDE_FIELD(4)
   uchar LCR;                                /* Line control Register      */
   STRIDE_FIELD(5)
   uchar MCR;                                /* Modem control register     */
   STRIDE_FIELD(6)
   uchar LSR;                                /* Line Status Register       */
   STRIDE_FIELD(7)
   uchar MSR;                                /* Modem status Register      */
   STRIDE_FIELD(8)
   uchar SCRATCHPAD;                         /* Uart scratchpad register   */
   RES_FIELD_BE UNDEF[8];
   STRIDE_FIELD(9)
   uchar DSR;                                /* DMA status register        */

} ST16550_UART_STRUCT, _PTR_ ST16550_UART_STRUCT_PTR;


typedef struct st16550_parallel_port_struct
{
   STRIDE_FIELD(1)
   uchar DATA;                               /* data in/out                */
   STRIDE_FIELD(2)
   uchar STATUS;                             /* Status register            */
   STRIDE_FIELD(3)
   uchar COMMAND;                            /* Command register           */
} ST16550_PARALLEL_PORT_STRUCT, _PTR_ ST16550_PARALLEL_PORT_STRUCT_PTR;
#endif /*(PSP_ENDIAN == MQX_LITTLE_ENDIAN) || defined(BSP_ST16550_LITTLE_ENDIAN)*/

typedef struct st16550_struct
{
   ST16550_UART_STRUCT           COM1;
   ST16550_UART_STRUCT           COM2;
   ST16550_PARALLEL_PORT_STRUCT  LPT1;
} ST16550_STRUCT, _PTR_ ST16550_STRUCT_PTR;


#endif /* _st16550_h_ */
